export class Promise {
    constructor(executor) {
      this.status = 'pending' 
      this.value = null 
      this.reason = null 
      this.onResovleCallbacks = []
      this.onRejectedCallbacks = []
      const resolve = (value) => {
        if (this.status === 'pending') {
          this.status = 'resolved'
          this.value = value
          this.onResovleCallbacks.forEach(fn => fn())
        }
      }
      const reject = (reason) => {
        if (this.status === 'pending') {
          this.status = 'rejected' 
          this.reason = reason
          this.onRejectedCallbacks.forEach(fn => fn())
        }
      }
      try {
        executor(resolve, reject) //默认为执行器执行
      } catch (error) {
        reject(error)
      }
    }
    then(onFufilled, onRejected) {
      onFufilled = typeof onFufilled === 'function' ? onFufilled : value => value
      onRejected = typeof onRejected === 'function' ? onRejected : error => {
        throw error
      }
      const resolvePromise = (promise1, xpromise, resolve, reject) => {
          // xpromise 可能是别人写的，所以判断一下
        if (promise1 === xpromise) { 
          return reject(new TypeError('循环引用'))
        }
        let called;
        if (xpromise != null && (typeof xpromise === 'object' || typeof xpromise === 'function')) {
          try {
            const then = xpromise.then
            if (typeof then === 'function') {
              then.call(xpromise, y => {
                if (called) return
                called = true
                resolvePromise(promise1, y, resolve, reject)
              }, r => {
                if (called) return
                called = true
                reject(r)
              })
            } else {
              resolve(xpromise)
            }
          } catch (e) { 
            if (called) return
            called = true
            reject(e)
          }
        } else { 
          resolve(xpromise)
        }
      }
      const promise1 = new Promise((resolve, reject) => {
        if (this.status === 'resolved') {
          setTimeout(() => {
            try {
              const x = onFufilled(this.value)
              resolvePromise(promise1, x, resolve, reject)
            } catch (e) {
              reject(e)
            }
          }, 0)
        }
        if (this.status === 'rejected') {
          setTimeout(() => {
            try {
              const x = onRejected(this.reason)
              resolvePromise(promise1, x, resolve, reject)
            } catch (e) {
              reject(e)
            }
          }, 0)
        }
        if (this.status === 'pending') {
          this.onResovleCallbacks.push(() => {
            setTimeout(() => {
              try {
                let x = onFufilled(this.value)
                resolvePromise(promise1, x, resolve, reject)
              } catch (e) {
                reject(e)
              }
            }, 0)
          });
          this.onRejectedCallbacks.push(() => {
            setTimeout(() => {
              try {
                const x = onRejected(this.reason)
                resolvePromise(promise1, x, resolve, reject)
              } catch (e) {
                reject(e)
              }
            }, 0)
          })
        }
      })
      return promise1
    }
  }